package model.skill;

import java.util.HashMap;
import java.util.Map;

import model.entity.BasicEntity;
import model.entity.Entity;
import model.entity.stats.Stat;
import model.entity.stats.StatSet;
import model.entity.stats.StatType;
import model.map.Location;

public class Observation extends NonactivateableSkill {

	private Map<BasicEntity,StatSet> oldStatMap;
	private Map<BasicEntity,StatSet> wackedStatMap;
	private Map<BasicEntity,Double> distanceBetween;
	private StatSet wackedStats;

	public Observation()
	{
		super(SkillType.OBSERVATION, SkillType.OBSERVATION);
		oldStatMap = new HashMap<BasicEntity,StatSet>();
		wackedStatMap = new HashMap<BasicEntity,StatSet>();
		distanceBetween = new HashMap<BasicEntity,Double>();
	}

	/*
		 public Observation(Map<Entity, StatSet> observation)
		 {
		 super("Observation", SkillType.OBSERVATION);
		 this.observation = observation;
		 }
		 */

	public StatSet getStats(BasicEntity source, BasicEntity target)
	{
		double distance;
		double targetHealth;
		double sourceObservationValue;
		Stat wackedStat;

		distance = distanceBetween(source, target);
		targetHealth = target.getStatVal(StatType.HP);

		if(oldStatMap.containsKey(target)){
			if( distanceBetween.get(target) == distance && 
					targetHealth == oldStatMap.get(target).getStatVal(StatType.HP) ){
				// values haven't changed
				return wackedStatMap.get(target);
			}
		}

		oldStatMap.put(target, target.getStats());
		distanceBetween.put(target, distance);

		sourceObservationValue = source.getStatVal(StatType.OBSERVATION);

		wackedStat = wackStat(new Stat(targetHealth, StatType.HP), distance, sourceObservationValue);
		wackedStats.addStat(StatType.HP, wackedStat);
		wackedStatMap.put(target, wackedStats);

		return wackedStats;
	}

	private double distanceBetween(BasicEntity ea, BasicEntity eb){
		Location eaLoc = ea.getLocation();
		Location ebLoc = eb.getLocation();

		int eax = eaLoc.getX();
		int ebx = ebLoc.getX();
		int eay = eaLoc.getY();
		int eby = ebLoc.getY();

		int xDiff = eax - ebx;
		int yDiff = eay - eby;

		return Math.sqrt(Math.pow((double)xDiff, 2.0) + Math.pow((double)yDiff, 2.0));
	}

	private Stat wackStat(Stat actualStat, double distance, double observation){
		double actualHealth = actualStat.getValue();
		double constant = 50.0;
		double variance = ((distance*constant)/observation);
		double max = actualHealth + variance;
		double min;

		if ( actualHealth > variance )
			min = actualHealth - variance;
		else
			min = 1.00;

		double wackStatVal = min + (Math.random() * ((max - min) + 1));
		Stat wackedStat = new Stat(wackStatVal, StatType.HP);

		return wackedStat;
	}
	
}
